package com.doeis.core.db.transaction;

import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Savepoint;
import org.apache.log4j.Logger;

public class TransactionManager {
	private static TransactionManager txManager = new TransactionManager();
	private static Logger log = Logger.getLogger(TransactionSynchronizer.class);

	public static TransactionManager getInstance() {
		return txManager;
	}

	public Transaction getTransaction(String datasourceName, String method) throws Exception {
		Transaction transaction = new Transaction();
		transaction.setDatasource(datasourceName);
		transaction.setMethod(method);
		TransactionSynchronizer.addTransaction(datasourceName, transaction);
		log.debug("start transaction:" + transaction.getMethod());
		return transaction;
	}

	public void commit(String datasourceName, Transaction transaction) throws Exception {
		int propagation = transaction.getPropagation();
		Connection conn = transaction.getConn();
		try {
			if (conn == null) {
				return;
			}
			if ((propagation == 0) || (propagation == 1)) {
				if (propagation == 1) {
					Savepoint savepoint = conn.setSavepoint();
					TransactionSynchronizer.addSavepoint(datasourceName, savepoint);
				}

				if (TransactionSynchronizer.isTopTransaction(datasourceName, transaction)) {
					conn.commit();

					TransactionSynchronizer.removeAllSavepoint(datasourceName);
				}
			} else {
				conn.commit();
			}

			log.debug("commit transaction ok:" + transaction.getMethod());
		} catch (Exception e) {
			throw new Exception("do Commit failed:", e);
		}
	}

	public void commit(String datasourceName) throws Exception {
		Transaction transaction = null;
		transaction = TransactionSynchronizer.getLastTransaction(datasourceName);
		if (transaction != null)
			commit(datasourceName, transaction);
	}

	public void rollback(String datasourceName, Transaction transaction) throws Exception {
		try {
			Connection conn = transaction.getConn();
			if (conn == null)
				return;
			try {
				conn.rollback();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		} catch (Exception e) {
			throw new Exception("DoRollBack failed:", e);
		} finally {
			TransactionSynchronizer.removeTransaction(datasourceName, transaction);
		}
		TransactionSynchronizer.removeTransaction(datasourceName, transaction);
	}

	public void rollback(String datasourceName) throws Exception {
		Transaction transaction = TransactionSynchronizer.getLastTransaction(datasourceName);
		if (transaction == null) {
			return;
		}
		rollback(datasourceName, transaction);
	}
}